package com.lixh.sdk.base.presentation

import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.app.Presentation
import android.content.Context
import android.os.Bundle
import android.view.Display
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LifecycleRegistry
import androidx.lifecycle.setViewTreeLifecycleOwner
import androidx.savedstate.SavedStateRegistry
import androidx.savedstate.SavedStateRegistryController
import androidx.savedstate.SavedStateRegistryOwner
import androidx.savedstate.setViewTreeSavedStateRegistryOwner
import com.lixh.sdk.base.anyModelScope
import com.lixh.sdk.base.util.log
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch


abstract class BasePresentation<S, E, F>(
    context: Context,
    display: Display,
    theme: Int,
) : Presentation(context, display, theme), LifecycleOwner, SavedStateRegistryOwner,
    AnalyticsDelegate by AnalyticsDelegateImpl() {
    companion object {
        const val TAG = "BasePresentation"
    }

    private var mContent: View? = null
    private var mBeginDialogWidth = 0
    private var mBeginDialogHeight = 0

    private val initialState: S by lazy { initialState() }

    private val _uiState: MutableStateFlow<S> by lazy { MutableStateFlow(initialState) }

    val uiState: StateFlow<S> by lazy { _uiState }

    private val _uiEvent: MutableSharedFlow<E> = MutableSharedFlow()

    private val _uiEffect: MutableSharedFlow<F> = MutableSharedFlow()
    val uiEffect: Flow<F> = _uiEffect

    protected abstract fun initialState(): S
    protected abstract suspend fun handleEvent(event: E, state: S): S?

    protected abstract fun initView()


    private var _lifecycleRegistry: LifecycleRegistry? = null
    private val lifecycleRegistry: LifecycleRegistry
        get() = _lifecycleRegistry ?: LifecycleRegistry(this).also {
            _lifecycleRegistry = it
        }
    private val savedStateRegistryController: SavedStateRegistryController by lazy {
        SavedStateRegistryController.create(this)
    }
    override val savedStateRegistry: SavedStateRegistry
        get() = savedStateRegistryController.savedStateRegistry

    override val lifecycle: Lifecycle
        get() = lifecycleRegistry

    override fun onSaveInstanceState(): Bundle {
        val bundle = super.onSaveInstanceState()
        savedStateRegistryController.performSave(bundle)
        return bundle
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        savedStateRegistryController.performRestore(savedInstanceState)
        lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)
        fixScreen()
        initView()
    }

    override fun onStart() {
        super.onStart()
        lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME)
    }

    override fun onStop() {
        lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY)
        _lifecycleRegistry = null
        super.onStop()
    }

    override fun setContentView(layoutResID: Int) {
        initViewTreeOwners()
        super.setContentView(layoutResID)
    }

    override fun setContentView(view: View) {
        initViewTreeOwners()
        super.setContentView(view)
    }

    override fun setContentView(view: View, params: ViewGroup.LayoutParams?) {
        initViewTreeOwners()
        super.setContentView(view, params)
    }

    override fun addContentView(view: View, params: ViewGroup.LayoutParams?) {
        initViewTreeOwners()
        super.addContentView(view, params)
    }


    private fun initViewTreeOwners() {
        window!!.decorView.setViewTreeLifecycleOwner(this)
        window!!.decorView.setViewTreeSavedStateRegistryOwner(this)
    }

    init {
        subscribeEvents()
    }

    protected fun sendEffect(effect: F) {
        anyModelScope.launch { _uiEffect.emit(effect) }
    }

    fun sendEvent(event: E) {
        anyModelScope.launch {
            _uiEvent.emit(event)
        }
    }

    /**
     * 收集事件
     */
    private fun subscribeEvents() {
        anyModelScope.launch {
            _uiEvent.collect {
                reduceEvent(_uiState.value, it)
            }
        }
    }


    /**
     * 处理事件，更新状态
     * @param state S
     * @param event E
     */
    private fun reduceEvent(state: S, event: E) {
        anyModelScope.launch {
            handleEvent(event, state)?.let { newState -> sendState { newState } }
        }
    }

    private fun sendState(newState: S.() -> S) {
        _uiState.value = uiState.value.newState()
    }

    private fun fixScreen() {
        setOnShowListener {
            "副屏action已启动 setOnShowListener".log(TAG)
            window?.apply {
                findViewById<View>(android.R.id.content).apply {
                    "副屏action已启动 this==$this".log(TAG)
                    mContent = this
                    mBeginDialogWidth = width
                    mBeginDialogHeight = height
                    startRotation()
                }
            }
            "副屏action已启动".log(TAG)
        }
        setOnDismissListener {
            "副屏action消失".log(TAG)
        }
    }

    private fun startRotation(rotation: Int = 3) {
        if (mContent == null) {
            return
        }
        val w: Float
        val h: Float
        val tranX: Float
        val tranY: Float
        if (rotation == 1 || rotation == 3) {//横屏
            w = mBeginDialogHeight.toFloat()
            h = mBeginDialogWidth.toFloat()
            tranX = (h - w) / 2
            tranY = (w - h) / 2
            window?.setLayout(h.toInt(), w.toInt())
        } else {
            w = mBeginDialogWidth.toFloat()
            h = mBeginDialogHeight.toFloat()
            tranX = 0f
            tranY = 0f
            window?.setLayout(
                ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.WRAP_CONTENT
            );
        }

        mContent!!.layoutParams.width = w.toInt()
        mContent!!.layoutParams.height = h.toInt()
        mContent!!.layoutParams = mContent!!.layoutParams


        mContent!!.animate()
            .rotation(90f * rotation)
            .translationX(tranX)
            .translationY(tranY).setDuration(0).setListener(object : AnimatorListenerAdapter() {
                override fun onAnimationEnd(animation: Animator) {
                    super.onAnimationEnd(animation)
                    "副屏已启动 动画结束".log(TAG)
                }
            })
    }

    fun toFront() {
        "副屏toFront".log(TAG)
        show()
    }

    //进入后台
    fun toBack() {
        "副屏toBack".log(TAG)
        hide()
    }
}